#include <iostream>
#include <ctime>
#include "PriorityQueue.h"

using namespace std;

typedef PriorityQueue<int,int>::DataBase db;

void pq_print(PriorityQueue<int,int> & pq) {
    PriorityQueue<int,int> _pq(pq);
    while (!_pq.isEmpty()) {
        cout<<_pq.findMin()<<" ";
        _pq.deleteMin();
    }
    cout<<endl;
}

bool in_check(int k,vector<int> & vec) {
    bool check=false;
    for (int i=0;i<vec.size();++i)
        if (k==vec[i])
            check=true;
    return check;
}

int main() {
    char mod='o';
    cout<<"Welcome to test : "<<endl;
    cout<<"i : test of insert() / d : test of deleteMin() / b : test of buildHeap()"<<endl;
    cout<<"r : test of remove() / m : test of modifyData() / M : test of merge()"<<endl;
    cout<<"o : exit"<<endl;
    cout<<"Please input mod to test , i or ... or M or o ? : ";
    while (cin>>mod && mod!='o') {
        
        if (mod=='i') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d;
            cout<<"Already create an empty pq for you."<<endl;
            cout<<"now input one key and one data , if key=0 then exit."<<endl;
            while (cin>>k>>d && k) {
                if (in_check(k,vec_key))
                    cout<<"key "<<k<<" already exist! change a key please."<<endl;
                else {
                    vec_key.push_back(k);
                    vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
                    clock_t start=clock();
                    pq.insert(vec.back());
                    clock_t end=clock();
                    cout<<"spend time : "<<(end-start)<<endl;
                    cout<<"Now pq is like this : ";
                    pq_print(pq);
                }
                cout<<"now input one key and one data , if key=0 then exit."<<endl;
            }
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else if (mod=='d') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d;
            cout<<"Already create an empty pq for you."<<endl;
            cout<<"please input 5 couples of key and data : "<<endl;
            cout<<"for example: 1 2 3 4 5 6 7 8 9 10"<<endl;
            for (int i=0;i<5;++i) {
                cin>>k>>d;
                vec_key.push_back(k);
                vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
            }
            pq.buildHeap(vec);
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"now deleteMin. "<<endl;
            clock_t start=clock();
            pq.deleteMin();
            clock_t end=clock();
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"spend time : "<<(end-start)<<endl;
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else if (mod=='b') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d,n;
            cout<<"how many(n) couples of key&data want to input ? : ";
            cin>>n;
            cout<<"now input n couples of key&data : "<<endl;
            while (n--) {
                cin>>k>>d;
                if (!in_check(k,vec_key)) {
                    vec_key.push_back(k);
                    vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
                }
            }
            cout<<"now buildhHeap() : "<<endl;
            clock_t start=clock();
            pq.buildHeap(vec);
            clock_t end=clock();
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"spend time : "<<(end-start)<<endl;
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else if (mod=='r') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d;
            cout<<"Already create an empty pq for you."<<endl;
            cout<<"please input 5 couples of key and data : "<<endl;
            cout<<"(for example: 1 2 3 4 5 6 7 8 9 10)"<<endl;
            cout<<"(please make sure no repeat key)"<<endl;
            for (int i=0;i<5;++i) {
                cin>>k>>d;
                vec_key.push_back(k);
                vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
            }
            pq.buildHeap(vec);
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"now remove which key? : "<<endl;
            cin>>k;
            clock_t start=clock();
            pq.remove(k);
            clock_t end=clock();
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"spend time : "<<(end-start)<<endl;
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else if (mod=='m') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d;
            cout<<"Already create an empty pq for you."<<endl;
            cout<<"please input 5 couples of key and data : "<<endl;
            cout<<"(for example: 1 2 3 4 5 6 7 8 9 10)"<<endl;
            cout<<"(please make sure no repeat key)"<<endl;
            for (int i=0;i<5;++i) {
                cin>>k>>d;
                vec_key.push_back(k);
                vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
            }
            pq.buildHeap(vec);
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"now modify which key? how many data? input key and data : "<<endl;
            cin>>k>>d;
            clock_t start=clock();
            pq.modifyData(k,d);
            clock_t end=clock();
            cout<<"now pq is like this : "<<endl;
            pq_print(pq);
            cout<<"spend time : "<<(end-start)<<endl;
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else if (mod=='M') {
            cout<<"-------------------------------------------------------------"<<endl;
            PriorityQueue<int,int> pq1,pq2;
            vector<PriorityQueue<int,int>::DataBase> vec;
            vector<int> vec_key;
            int k,d,n;
            cout<<"already create two empty priorityqueue pq1 and pq2"<<endl;
            cout<<"how many(n) couples of key&data want to input to pq1? : ";
            cin>>n;
            cout<<"now input n couples of key&data : "<<endl;
            while (n--) {
                cin>>k>>d;
                if (!in_check(k,vec_key)) {
                    vec_key.push_back(k);
                    vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
                }
            }
            pq1.buildHeap(vec);
            vec.clear();
            vec_key.clear();
            cout<<"how many(n) couples of key&data want to input to pq2? : ";
            cin>>n;
            cout<<"now input n couples of key&data : "<<endl;
            while (n--) {
                cin>>k>>d;
                if (!in_check(k,vec_key)) {
                    vec_key.push_back(k);
                    vec.push_back(PriorityQueue<int,int>::DataBase(k,d));
                }
            }
            pq2.buildHeap(vec);
            cout<<"now pq1 is like this : "<<endl;
            pq_print(pq1);
            cout<<"now pq2 is like this : "<<endl;
            pq_print(pq2);
            cout<<"now merge pq2 to pq1 : "<<endl;
            clock_t start=clock();
            pq1.merge(pq2);
            clock_t end=clock();
            cout<<"now pq1 is like this : "<<endl;
            pq_print(pq1);
            cout<<"spend time : "<<(end-start)<<endl;
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        else {
            cout<<"-------------------------------------------------------------"<<endl;
            cout<<"Illegal input , please input again.";
            cout<<"-------------------------------------------------------------"<<endl;
        }
        
        cout<<"i : test of insert() / d : test of deleteMin() / b : test of buildHeap()"<<endl;
        cout<<"r : test of remove() / m : test of modifyData() / M : test of merge()"<<endl;
        cout<<"o : exit"<<endl;
        cout<<"Please input mod to test , i or ... or M or o ? : ";
    }
    cout<<"Thanks for testing!"<<endl;
}
